package cn.shiwei.user.service.impl;

import cn.shiwei.basic.constants.UserConstants;
import cn.shiwei.basic.exception.MyException;
import cn.shiwei.basic.service.impl.BaseServiceImpl;
import cn.shiwei.basic.util.LoginContextUtil;
import cn.shiwei.basic.util.MD5Utils;
import cn.shiwei.basic.util.PhoneNumberUtils;
import cn.shiwei.basic.util.StrUtils;
import cn.shiwei.user.domain.Logininfo;
import cn.shiwei.user.domain.User;
import cn.shiwei.user.domain.UserAddress;
import cn.shiwei.user.domain.UserDto;
import cn.shiwei.user.mapper.LogininfoMapper;
import cn.shiwei.user.mapper.UserAddressMapper;
import cn.shiwei.user.mapper.UserMapper;
import cn.shiwei.user.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserAddressMapper userAddressMapper;

    @Override
    public void sendMsg(Map<String, String> map) {
        String phone = map.get("phone");
        String type = map.get("type");
/*        if (!PhoneNumberUtils.isPhoneNumber(phone)){
            System.out.println(phone + "号码错误");
            throw new MyException("请输入正确的手机号");
        }*/
        if (StringUtils.isEmpty(type)){
            throw new MyException("手机号不能为空");
        }

        if ("binder".equals(type)){
            /*if (userMapper.findByPhone(phone).get){

            }*/
            code(phone, UserConstants.BINDER_CODE_PREFIX);
        } else {
            if (userMapper.findByPhone(phone) != null){
                throw new MyException("手机号已注册, 请直接登录");
            }
            code(phone, UserConstants.REGISTER_CODE_PREFIX);
        }
    }

    public void code(String phone, String prefixCode){
        // 获取随机的6位验证码
        String msgCode = StrUtils.getComplexRandomString(6);
        System.out.println(msgCode);
        // 组装key
        String verificationCode = prefixCode.concat(phone);
        // 从redis中尝试获取验证码
        String code = (String) redisTemplate.opsForValue().get(verificationCode);
        // 获取当前时间戳
        long newTime = System.currentTimeMillis();
        long oneMinutes = 60 * 1000;
        // 如果从redis中获取的验证码不为空
        if (code != null) {
            // 获取原验证码前拼接的时间戳
            String time = code.substring(0, code.indexOf(":"));
            // 判断时间戳之差是否小于1min, 小于1min抛异常
            if (newTime - Long.valueOf(time) < oneMinutes) {
                throw new MyException("系统繁忙");
            } else {
                // 覆盖验证码
                msgCode = code.substring(code.indexOf(":") + 1);
            }
        }
        // 拼接新的验证码
        code = newTime + ":" + msgCode;
        System.out.println("获取的验证码: " + msgCode);
        // 设置验证码, 设置过期时间
        redisTemplate.opsForValue().set(verificationCode, code, 3L, TimeUnit.MINUTES);
        // 发送验证码
        // SendMsg.sendMsg(phone,msgCode);
    }


    @Override
    @Transactional
    public void register(UserDto userDto) {

        String phone = userDto.getPhone();
        String password = userDto.getPassword();
        String confirmPwd = userDto.getConfirmPwd();
        String verifyCode = userDto.getVerifyCode();

        // 获取key
        String verificationCode = UserConstants.REGISTER_CODE_PREFIX.concat(phone);
        // 获取value
        String code = (String)redisTemplate.opsForValue().get(verificationCode);


        // 非空判断
        if (StringUtils.isEmpty(phone)
                || StringUtils.isEmpty(password)
                || StringUtils.isEmpty(verifyCode)
                || StringUtils.isEmpty(confirmPwd)
                ){
            throw new MyException("手机号/验证码/一次密码/二次密码 不能为空");
        }

        // 判断手机号是否已经注册
        if (userMapper.findByPhone(phone) != null){
            throw new MyException("手机号已注册, 请直接登录");
        }

        // 判断两次输入的密码是否一致
        if (!password.equals(confirmPwd)){
            throw new MyException("两次输入的密码不一样");
        }

        // 校验验证码过期
        if (code == null){
            throw new MyException("验证码失效");
        } else {
            code = code.substring(code.indexOf(":") + 1);
            // 用户输入的验证码与服务器的不一致
            if (!code.equalsIgnoreCase(verifyCode)){
                throw new MyException("验证码错误");
            }
        }

        // 组装用户数据和登录数据
        Logininfo logininfo = new Logininfo(phone, password,UserConstants.USER_TYPE);
        User user = new User(phone, password, UserConstants.USER_STATE_ENABLE);

        // 保存用户登录信息, 返回主键
        logininfoMapper.save(logininfo);

        // 保存用户信息
        user.setLogininfo(logininfo);
        userMapper.save(user);
    }

    @Override
    public List<UserAddress> loadAddressByLogininId(Long id) {
        if (id == null){
            throw new MyException("登录状态异常, 请退出登录后重试");
        }
        List<UserAddress> adds = userAddressMapper.loadAddressByLogininId(id);
        return adds;
    }

    @Override
    public void saveAddress(UserAddress userAddress) {
        Long id = LoginContextUtil.getLoininfo().getId();
        Long uid = userMapper.loadByLogininfoId(id).getId();
        userAddress.setUserId(uid);
        userAddressMapper.save(userAddress);

    }
}
